/**
 * 
 */
package com.googlecode.cswish.struts.interceptor;

import java.util.ArrayList;
import java.util.List;

import ognl.OgnlRuntime;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.cswish.struts.DynamicAction;
import com.googlecode.cswish.struts.InstantiatingNullHandler;
import com.googlecode.cswish.struts.ListPropertyAccessor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
 * Enhance the default implement<br>
 * 
 * 1. Initialize the parameter according to ParamScope define
 * <p>
 * There's 2 places to define the scope:
 * <li> Use ParamScope in the Action class or business method
 * <li> Call "ps.scope" in the FreeMarker page
 * 
 * @author Jerry.Feng Date: 2008-4-2
 *
 */
public class ScopeParametersInterceptor extends AbstractInterceptor {
	
	private static final Log LOG = LogFactory.getLog(ScopeParametersInterceptor.class);

	@Inject
	public void setContainer(Container container) {
		InstantiatingNullHandler nullHandler = new InstantiatingNullHandler();
		container.inject(nullHandler);
		OgnlRuntime.setNullHandler(Object.class, nullHandler);
		OgnlRuntime.setNullHandler(Object[].class, nullHandler);
		
		ListPropertyAccessor listPropertyAccessor = new ListPropertyAccessor();
		container.inject(listPropertyAccessor);
		OgnlRuntime.setPropertyAccessor(List.class, listPropertyAccessor);
		OgnlRuntime.setPropertyAccessor(ArrayList.class, listPropertyAccessor);
	}
	
	public String intercept(ActionInvocation invocation) throws Exception {
		// create the parameter object according to annotation
		updateAnnotationScope(invocation);
		
		return invocation.invoke();
	}
	
	private void updateAnnotationScope(ActionInvocation invocation){
		if (invocation.getAction() instanceof DynamicAction) {
			DynamicAction prepareAction = (DynamicAction) invocation.getAction();
			prepareAction.prepareParameter(invocation);
		}
	}
}
